
exports.__esModule = true;
exports.default = void 0;

const _style = require('../utils/dom/style');

const _utils = require('../utils');

const _scroll = require('../utils/dom/scroll');

const _bindEvent = require('../mixins/bind-event');

const _createNamespace = (0, _utils.createNamespace)('sticky');
const createComponent = _createNamespace[0];
const bem = _createNamespace[1];

const _default = createComponent({
  mixins: [(0, _bindEvent.BindEventMixin)(function (bind, isBind) {
    if (!this.scroller) {
      this.scroller = (0, _scroll.getScroller)(this.$el);
    }

    if (this.observer) {
      const method = isBind ? 'observe' : 'unobserve';
      this.observer[method](this.$el);
    }

    bind(this.scroller, 'scroll', this.onScroll, true);
    this.onScroll();
  })],
  props: {
    zIndex: [Number, String],
    container: null,
    offsetTop: {
      type: [Number, String],
      default: 0,
    },
  },
  data: function data() {
    return {
      fixed: false,
      height: 0,
      transform: 0,
    };
  },
  computed: {
    style: function style() {
      if (!this.fixed) {
        return;
      }

      const style = {};

      if ((0, _utils.isDef)(this.zIndex)) {
        style.zIndex = this.zIndex;
      }

      if (this.offsetTop && this.fixed) {
        style.top = `${this.offsetTop}px`;
      }

      if (this.transform) {
        style.transform = `translate3d(0, ${this.transform}px, 0)`;
      }

      return style;
    },
  },
  created: function created() {
    const _this = this;

    // compatibility: https://caniuse.com/#feat=intersectionobserver
    if (!_utils.isServer && window.IntersectionObserver) {
      this.observer = new IntersectionObserver(((entries) => {
        // trigger scroll when visibility changed
        if (entries[0].intersectionRatio > 0) {
          _this.onScroll();
        }
      }), {
        root: document.body,
      });
    }
  },
  methods: {
    onScroll: function onScroll() {
      const _this2 = this;

      if ((0, _style.isHidden)(this.$el)) {
        return;
      }

      this.height = this.$el.offsetHeight;
      const { container } = this;
      const offsetTop = +this.offsetTop;
      const scrollTop = (0, _scroll.getScrollTop)(window);
      const topToPageTop = (0, _scroll.getElementTop)(this.$el);

      const emitScrollEvent = function emitScrollEvent() {
        _this2.$emit('scroll', {
          scrollTop,
          isFixed: _this2.fixed,
        });
      }; // The sticky component should be kept inside the container element


      if (container) {
        const bottomToPageTop = topToPageTop + container.offsetHeight;

        if (scrollTop + offsetTop + this.height > bottomToPageTop) {
          const distanceToBottom = this.height + scrollTop - bottomToPageTop;

          if (distanceToBottom < this.height) {
            this.fixed = true;
            this.transform = -(distanceToBottom + offsetTop);
          } else {
            this.fixed = false;
          }

          emitScrollEvent();
          return;
        }
      }

      if (scrollTop + offsetTop > topToPageTop) {
        this.fixed = true;
        this.transform = 0;
      } else {
        this.fixed = false;
      }

      emitScrollEvent();
    },
  },
  render: function render() {
    const h = arguments[0];
    const { fixed } = this;
    const style = {
      height: fixed ? `${this.height}px` : null,
    };
    return h('div', {
      style,
    }, [h('div', {
      class: bem({
        fixed,
      }),
      style: this.style,
    }, [this.slots()])]);
  },
});

exports.default = _default;
